import numpy as np
# 1. 核心算法实现
def max_pool2d(x,kernel_size=2,stride=2):
    N,C,H,W = x.shape
    H_out = (H - kernel_size) // stride + 1
    W_out = (W - kernel_size) // stride + 1
    output = np.zeros((N,C,H_out,W_out))
    for n in range(N):
        for c in range(C):
            for h in range(H_out):
                for w in range(W_out):
                    h_start = h * stride
                    w_start = w * stride
                    region = x[n,c,h_start:h_start+kernel_size,w_start:w_start+kernel_size]
                    output[n,c,h,w] = np.max(region)
    return output
def avg_pool2d(x,kernel_size=2,stride=2):
    N,C,H,W = x.shape
    H_out = (H - kernel_size) // stride + 1
    W_out = (W - kernel_size) // stride + 1
    output = np.zeros((N,C,H_out,W_out))
    for n in range(N):
        for c in range(C):
            for h in range(H_out):
                for w in range(W_out):
                    h_start = h * stride
                    w_start = w * stride
                    region = x[n,c,h_start:h_start+kernel_size,w_start:w_start+kernel_size]
                    output[n,c,h,w] = np.mean(region)
    return output
# 2. 测试数据构造
print("=== 测试数据构造 ===")
# 第一个特征图：左上角2x2区域有显著激活
feature_map1 = np.array([[
    [8,9,1,2],
    [7,8,1,2],
    [1,1,2,1],
    [2,1,1,2]
]],dtype=np.float32).reshape(1,1,4,4)
# 第二个特征图：将激活模式向右平移1个像素（循环填充）
feature_map2 = np.array([[
    [2,8,9,1],
    [2,7,8,1],
    [1,1,1,2],
    [2,2,1,1]
]],dtype=np.float32).reshape(1,1,4,4)
# 3. 池化实验
print("\n=== 最大池化实验 ===")
# 对两个特征图执行最大池化
max_pooled1 = max_pool2d(feature_map1,kernel_size=2,stride=2)
max_pooled2 = max_pool2d(feature_map2,kernel_size=2,stride=2)
print("最大池化 - 特征图1结果:")
print(max_pooled1[0,0])
print("最大池化 - 特征图2结果:")
print(max_pooled2[0,0])
print("\n=== 平均池化实验 ===")
# 对两个特征图执行平均池化
avg_pooled1 = avg_pool2d(feature_map1,kernel_size=2,stride=2)
avg_pooled2 = avg_pool2d(feature_map2,kernel_size=2,stride=2)
print("平均池化 - 特征图1结果:")
print(avg_pooled1[0,0])
print("平均池化 - 特征图2结果:")
print(avg_pooled2[0,0])
# 尺寸对比
print("\n=== 尺寸对比 ===")
print(f"池化前尺寸:{feature_map1.shape[2:]} -> 池化后尺寸:{max_pooled1.shape[2:]}")
print(f"尺寸减少:{feature_map1.shape[2]*feature_map1.shape[3]//max_pooled1.shape[2]//max_pooled1.shape[3]}倍")
# 两种池化方法对比
print("\n=== 两种池化方法对比 ===")
print("最大池化 - 平移不变性:")
print("结果是否相同:",np.array_equal(max_pooled1,max_pooled2))
print("最大激活值:",np.max(max_pooled1),np.max(max_pooled2))
print("\n平均池化 - 平移不变性:")
print("结果是否相同:",np.array_equal(avg_pooled1,avg_pooled2))
print("最大激活值:",np.max(avg_pooled1),np.max(avg_pooled2))
print("\n特征保持能力对比:")
print("最大池化保持峰值特征,平均池化保持整体信息")
print(f"最大池化峰值:{np.max(max_pooled1):.1f} vs 平均池化峰值:{np.max(avg_pooled1):.1f}")
